home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n07.arc
/
ENCORE.ARC
/
ENCORE.ASM
next >
Wrap
Assembly Source File
|
1991-03-27
|
21KB
|
746 lines
;Portions of this code are copyrighted 1990
;by RSE Incorporated and used with permission
Code segment byte public 'code'
assume cs:code
assume ds:code
org 100h
LGo: jmp Init
BoostDelay dw 18 ;# of clock ticks (18.2/sec)
BufSize dw 500 ;buffer size in bytes (5 per keystroke)
CapSS db 4 ;1=RShft 2=LShft 4=Ctrl 8=Alt 12=Ctrl-Alt
CapSC db 19 ;Ctrl-R record hot key
RepSS db 4
RepSC db 25 ;Ctrl-P playback hot key
Delay dw 0 ;clock ticks since last key press
EndBuff dw 0 ;offset of end of buffer
Pntr dw offset Buffer ;offset where next key info goes
Cap? db 0 ;capture flag
UpperLimit dw 0
Shift db 0 ;shift value of key
Waet dw 0 ;keystroke delay
Key dw 0 ;ASCII and Scan Code of key
KeyBufEnd dw 0 ;end of BIOS key buffer
Replay? db 0 ;replay flag
Tick dw 0 ;keeps track of clock in sound proc
Remove? db 0 ;indicates if key press or release
Message db 'EncoreHere'
BuffOff dw offset StrBytes
BufSizOff dw offset BufSize
Vec9 dd 0 ;Int 9 original vector
Vec1C dd 0 ;Int 1C original vector
I9 proc
;activated anytime a key is pressed OR released
sti
push ax
push es
mov ax,40h
mov es,ax
mov ah,es:17h ;put shift state in ah
pop es
and ah,0Fh ;just want shift states
in al,60h ;get scan code of key press
and al,7Fh ;mask out release bit
I92: cmp al,cs:CapSC ;Record hot key scan code?
jne I93
jmp CapKey?
I93: cmp al,cs:RepSC ;playback hot key scan code?
jne I94
jmp ReplayKey?
I94: cmp cs:Replay?,1
jne I95
cmp al,1 ;Escape pressed during Replay?
jne I95
call EndReplay
mov cs:Remove?,1 ;I9end will changes this to 0
I945: call I9end
pop ax
iret
I95: cli
pushf
call cs:Vec9 ;call originial interupt
cmp cs:Cap?,1
je Capture
I96: pop ax
iret
;capturing - done after Vec9 is called
Capture: push es
mov ax,40h
mov es,ax
mov ax,es:1Ch
cmp ax,cs:KeyBufEnd
jne I97
;if tail of buffer hasn't changed (no new keys) then return
pop es
pop ax
iret
I97: mov cs:KeyBufEnd,ax
push di
push bx
mov di,cs:Pntr
;if key buffer is full then turn off capture
cmp di,cs:UpperLimit
jb I98
call EndCap
jmp I9a
;save key info
;format - first byte=ASCII, 2=Scan Code, 3=Shift state, 4&5=Delay
I98: add cs:Pntr,5
mov ax,cs:Delay
mov cs:[di+3],ax ;delay
mov cs:Delay,0
;get last key put into buffer (end of buffer-2)
mov ax,40h
mov es,ax
mov bx,es:1Ch ;end of BIOS buffer
cmp bx,1Eh ;remember, it's a circular buffer
jne I99
mov bx,3Eh
I99: dec bx
dec bx
mov ax,es:[bx]
mov cs:[di],ax ;ASCII (al) Scan Code (ah)
mov al,es:17h ;shift state
mov cs:[di+2],al
I9a: pop bx
pop di
pop es
pop ax
cli
iret
;Replay hot key pressed?
ReplayKey?: cmp cs:Remove?,1
je R20
cmp ah,cs:RepSS
je R1
jmp I94
;initiate replay
R1: cmp cs:Cap?,1
jne R2
;quit capturing before initiating replay
call EndCap
R2: mov cs:Pntr,offset Buffer
cmp cs:StrBytes,0
ja R21
R20: call I9end
pop ax
iret
R21: push di
push bx
push ds
mov ax,cs
mov ds,ax
;use size of key sequence to compute end of buffer
mov ax,StrBytes
add ax,offset Buffer
mov EndBuff,ax
call GetVars ;get key info
pop ds
pop bx
pop di
call I9end ;clear key from keyboard
mov cs:Delay,0 ;reset delay
pop ax
cli
mov cs:Replay?,1 ;set replay flag
iret
;capture hot key
CapKey?: cmp cs:Remove?,1
je R20
cmp ah,cs:CapSS
je Cap1
jmp I94
;Capture
Cap1: call I9end
cmp cs:Cap?,1 ;if already capturing then end
jne Cap2
;end capture
call EndCap
jmp Cap3
;starting capture
Cap2: call sound
;reset buffer info
mov cs:Delay,0
mov cs:Pntr,offset Buffer
mov cs:Cap?,1
push ax
mov ax,40h
mov es,ax
mov ax,es:1Ch
mov cs:KeyBufEnd,ax
pop es
Cap3: pop ax
iret
I9 endp
I9end proc
in al,61h ;resets the keyboard
mov ah,al
or al,80h
out 61h,al
mov al,ah
out 61h,al
cli
mov al,20h ;reset interupts
out 20h,al
sti
xor cs:Remove?,1
ret
I9end endp
EndCap proc ;ends capturing
cli
mov cs:Cap?,0
sti
call sound
call sound
;anything captured?
mov ax,cs:Pntr
;put size of key sequence StrBytes
EC1: mov cs:EndBuff,ax
sub ax,offset Buffer
mov cs:StrBytes,ax
ret
EndCap endp
I1C proc ;timer interupt
pushf
call cs:Vec1C ;call timer interupt
inc cs:Delay
cmp cs:Replay?,1
jae T1
iret ;if not replaying then we're done
;replaying
T1: sti
push ax
push di
push ds
mov ax,cs
mov ds,ax
mov ax,Delay
cmp ax,Waet ;waited long enough?
jb T4 ;return
;put stuff in
push es
push bx
mov ax,40h
mov es,ax
mov bx,es:1Ch ;adjust for circular buffer
cmp bx,es:1Ah
jne T3
mov ax,Key
mov es:[bx],ax ;put ASCII and Scan code in
inc bx
inc bx
cmp bx,3Eh
jne T2
mov bx,1Eh
T2: mov es:1Ch,bx ;adjust end of BIOS buffer
mov al,Shift
mov es:17h,al ;put shift state in
push bx
call GetVars ;get next key info
pop bx
T3: mov Delay,0 ;reset delay
pop bx
pop es
T4: pop ds
pop di
pop ax
iret
I1C endp
GetVars proc
;enter with Pntr pointing to variables and ds=cs
;returns Key (ASCII and Scan Code), Shift, and Waet
mov di,Pntr
GV1: mov ax,[di]
mov Key,ax
mov al,[di+2]
mov Shift,al
mov ax,[di+3]
cmp ax,BoostDelay ;check if Waet <= Boost value
ja GV3
GV2: xor ax,ax
GV3: mov Waet,ax
add di,5
mov Pntr,di
cmp di,EndBuff
ja EndReplay
ret
GetVars endp
EndReplay proc
;terminate replay
push es
mov ax,40h
mov es,ax
mov cs:Pntr,offset Buffer
mov cs:Replay?,0
mov al,es:17h ;get shift state
and al,0F0h ;eliminate shifts,ctrl,alt
mov es:17h,al ;restore shift state
pop es
ret
EndReplay endp
Sound proc ;destroys AX
push es
mov ax,40h
mov es,ax
mov ax,es:6Ch
S1: cmp es:6Ch,ax
je S1 ;wait till clock tick changes
inc ax
mov cs:tick,ax
mov al,0B6h
out 43h,al ;get timer ready
mov ax,0C00h
out 42h,al
mov al,ah
out 42h,al ;set freq
in al,61h
or al,3
out 61h,al ;turn speaker on
mov ax,cs:tick
S2: cmp ax,es:6Ch
je S2 ;do for one clock tick
in al,61h ;turn off speaker
and al,11111100b
out 61h,al
pop es
ret
Sound endp
Change? db 0 ;make command line changes permanent?
Dummy3 db 0
StrBytes dw 0
Buffer db 0
;buffer will overwrite the following code
Msg db 10,'ENCORE 1.0 Copyright (c) 1991 Ziff Communications Co.',13,10
db 'PC Magazine ~ Scott Chaney ~ RSE Inc',13,10,10
Msg0 db 'Syntax: ENCORE [/S] [/L] [/U] [/Kn../Bn../P]',13,10
db ' /S = Save a keystroke sequence to disk',13,10
db ' /L = Load a keystroke sequence (macro)',13,10
db ' /U = Uninstall',13,10
Msg1 db ' /Kn = Change size of keystroke buffer',13,10
db ' /Bn = Change Boost threshold (in clock ticks)',13,10
db ' /P = Make command line changes permanent',13,10
Msg2 db 'Ctrl-R = Record keystrokes',13,10
db 'Ctrl-P = Playback keystrokes',13,10,'$'
Already db 10,'Encore is already loaded',13,10,10,'$'
Init proc
push cs
pop ds
;check for command line
mov bx,80h
mov cl,[bx]
cmp cl,0
je P4
mov si,81h
Parse: mov al,[si]
inc si
cmp al,0Dh
je P4
cmp al,'/'
je Parse
cmp al,' '
je Parse
or al,20h ;convert to lower case
cmp al,'p' ;make command line changes perm?
jne P3
mov Change?,1
P3: cmp al,'k' ;change keystroke buffer size?
jne P32 ;Parse
call MakeNum
mov bx,5
mul bx
mov BufSize,ax
jmp Parse
P32: cmp al,'l' ;load in key file?
jne P34
mov Ld,1
jmp LdSv
P34: cmp al,'s' ;save to key file?
jne P35
jmp LdSv
P35: cmp al,'b' ;change boost value?
jne P36
call MakeNum
mov BoostDelay,ax
jmp Parse
P36: cmp al,'u' ;uninstall?
jne Parse
jmp UnInstall
P4: call Loaded?
jne P42
;already loaded into memory
mov ah,9
mov dx,offset Already
int 21h ;print 'already loaded'
mov Msg1,'$'
mov dx,offset Msg0
mov ah,9
int 21h
mov dx,offset Msg2
mov ah,9
int 21h
Outtahere: mov ah,4Ch
int 21h ;end
;make command line changes permanent?
P42: cmp Change?,1
jne P5
mov dx,offset FileName
mov ax,3D02h
int 21h ;open file
mov bx,ax ;file handle
mov dx,100h
mov cx,7
mov ah,40h
int 21h ;write 7 bytes to file
mov ah,3Eh
int 21h ;close file
P5: mov ah,9
mov dx,offset Msg
int 21h ;print copyright message
mov ax,cs:2Ch
mov es,ax
mov ah,49h
int 21h ;free environment memory
mov ax,3509h
int 21h ;get int 09 vector
mov word ptr Vec9,BX
mov word ptr Vec9[2],ES
mov ax,351Ch
int 21h ;get int vec 1C
mov word ptr Vec1C,bx
mov word ptr Vec1C[2],es
mov word ptr cs:[0100],0
mov bx,offset Buffer
add bx,BufSize
mov EndBuff,bx
mov UpperLimit,bx
mov cl,4
shr bx,cl ;paragraphs needed
sub bx,0Ah ;less 160 bytes code shifted
push bx
mov si,100h
mov cx,offset Buffer
sub cx,si
mov di,60h
push ds
pop es
cld
rep movsb ;mov code down 160 bytes
mov ax,ds
sub ax,0Ah
mov ds,ax
mov ax,2509h
mov dx,offset I9 ;set Int9 vector
int 21h
mov ax,251Ch
mov dx,offset I1C ;set Int1C vector
int 21h
pop dx
inc dx
MOV Ax,3100h
INT 21h ;terminate and stay resident
Init endp
MakeNum proc
;converts ASCII number to binary word
xor ax,ax
mov bx,0Ah
MN1: mov cl,[si]
cmp cl,'0'
jb MN2
cmp cl,'9'
ja MN2
mul bx
xor ch,ch
sub cl,'0'
add ax,cx
inc si
jmp MN1
MN2: ret
MakeNum endp
Ld db 0 ;1 if loading, 0 if saving
ExitMsg db 13,10,'Encore not loaded',13,10,'$'
NoFile db 13,10,'File not found',13,10,'$'
NoCreate db 13,10,'Unable to create file.',13,10,'$'
TooSmall db 13,10,'Buffer too small',13,10,'$'
Removed db 13,10,'Encore is uninstalled',13,10,'$'
Ext db '.ENC'
FileName db 'ENCORE.COM',4 dup (0)
StrSize dw 0
LdSv proc
;used to either save a key seq to file, or load a key seq from file
;si is already set by Init
;make filename
mov di,offset FileName
LS0: mov al,[si]
inc si
cmp al,0Dh
je LS1
cmp al,' '
je LS0
mov [di],al
inc di
jmp LS0
LS1: mov ax,word ptr Ext
mov [di],ax
mov ax, word ptr Ext+2
mov [di+2],ax
call Loaded?
je LS2
;Encore not in memory
mov dx, offset ExitMsg
mov ah,9
int 21h
mov ah,4Ch
int 21h
;move offset info from TSR into program
LS2: mov si,offset BuffOff
mov cx,4
LS3: mov al,es:[di]
mov [si],al
inc si
inc di
loop LS3
mov dx,offset FileName
xor cx,cx
mov ax,3D02h
cmp Ld,1
je LS4
dec ah
LS4: int 21h ;open filename, or create (if saving)
jnc LS6
;unable to open file
mov dx,offset NoFile
cmp Ld,1
je LS5
mov dx,offset NoCreate
LS5: mov ah,9
int 21h
mov ah,4Ch
int 21h
LS6: cmp Ld,1
jne LS8
;if loading key sequence from disk
mov bx,ax ;put file handle in bx
mov cx,2
mov ah,3Fh
mov dx,offset StrSize
int 21h ;read in StrSize
;check buffer size
mov si,BufSizOff
mov ax,es:[si]
cmp ax,StrSize
jae LS7
;not enough room in buffer
mov dx,offset TooSmall
mov ah,9
int 21h
jmp Endd
LS7: xor cx,cx
mov dx,cx
mov ax,4200h
int 21h ;move file ptr to beg of file
mov cx,StrSize
add cx,2
mov dx,BuffOff
push es
pop ds
mov ah,3Fh
int 21h ;read key seq into TSR's buffer
jmp Endd
;saving key sequence to disk
LS8: push ax ;file handle
mov bx,BuffOff
mov cx,es:[bx] ;size of key sequence
mov dx,bx
pop bx
push es
pop ds
mov ah,40h
int 21h ;save StrSize and key sequence
Endd: mov ah,3Eh
int 21h ;close file
mov ah,4Ch
int 21h ;end program
LdSv endp
;check if already loaded
Loaded? proc
;checks to see if TSR already is loaded. If it is then zf set upon
;return and es:di points to offset info in TSR
mov bx,offset Message
inc Message ;avoid disk cache match
mov ax,cs
mov dx,0A000h-1
NextPara: inc dx ;next paragraph
mov es,dx
cmp dx,ax
je NotHere ;If our seg then search is done
mov si,bx ;else check for match
mov di,bx
mov cx,0Ah
rep cmpsb ;a match?
jnz NextPara ;if no match, keep looking
ret
NotHere: inc ax
cmp ax,dx ;return with not equal
ret
Loaded? endp
UnInstall proc
call Loaded?
jne U2
;reset interupts to original values
mov dx,word ptr es:Vec9
mov ax,word ptr es:Vec9[2]
mov ds,ax
mov ax,2509h
int 21h ;reset int 9
mov dx,word ptr es:Vec1C
mov ax,word ptr es:Vec1C[2]
mov ds,ax
mov ax,251Ch ;reset int 1C
int 21h
mov ax,es
add ax,0Ah
mov es,ax
mov ah,49h
int 21h ;free memory block
push cs
pop ds
mov dx,offset Removed
mov ah,9
int 21h ;print message
U2: mov ah,4Ch
int 21h ;end
UnInstall endp
Code ends
end LGo